package main

import (
	"crypto/tls"
	"fmt"
	"github.com/gofiber/fiber/v3"
	"github.com/nacos-group/nacos-sdk-go/v2/clients"
	"github.com/nacos-group/nacos-sdk-go/v2/clients/naming_client"
	"github.com/nacos-group/nacos-sdk-go/v2/common/constant"
	"github.com/nacos-group/nacos-sdk-go/v2/model"
	"github.com/nacos-group/nacos-sdk-go/v2/vo"
	quic_grpc "github.com/nanakura/grpc-quic"
	"google.golang.org/grpc"
	hello_grpc "grpc-nacos/proto"
	"log"
)

func selectInstances(client naming_client.INamingClient, param vo.SelectInstancesParam) []model.Instance {
	instances, err := client.SelectInstances(param)
	if err != nil {
		panic("SelectInstances failed!" + err.Error())
	}
	return instances
}

func selectOneHealthyInstance(client naming_client.INamingClient, param vo.SelectOneHealthInstanceParam) *model.Instance {
	instances, err := client.SelectOneHealthyInstance(param)
	if err != nil {
		panic("SelectOneHealthyInstance failed!")
	}
	return instances
}

func main() {
	//create ServerConfig
	sc := []constant.ServerConfig{
		*constant.NewServerConfig("127.0.0.1", 8848),
	}

	//create ClientConfig
	cc := *constant.NewClientConfig(
		constant.WithNamespaceId(""),
		constant.WithTimeoutMs(5000),
		constant.WithNotLoadCacheAtStart(true),
		constant.WithLogLevel("debug"),
	)

	// create naming client
	client, err := clients.NewNamingClient(
		vo.NacosClientParam{
			ClientConfig:  &cc,
			ServerConfigs: sc,
		},
	)

	if err != nil {
		panic(err)
	}
	instance := selectOneHealthyInstance(client, vo.SelectOneHealthInstanceParam{
		ServiceName: "demo.go",
		GroupName:   "group-a",
		Clusters:    []string{"cluster-a"},
	})
	if instance == nil {
		log.Fatalf("No available instances for service")
	}
	cliTlsConf := &tls.Config{
		InsecureSkipVerify: true,
	}

	creds := quic_grpc.NewCredentials(cliTlsConf)

	dialer := quic_grpc.NewQuicDialer(cliTlsConf)
	grpcOpts := []grpc.DialOption{
		grpc.WithContextDialer(dialer),
		grpc.WithTransportCredentials(creds),
	}

	serverAddr := fmt.Sprintf("%s:%d", instance.Ip, instance.Port)
	log.Println("get grpc server:", serverAddr)
	grpcClient, err := grpc.Dial(serverAddr, grpcOpts...)
	if err != nil {
		panic(err)
	}
	fooServiceClient := hello_grpc.NewFooServiceClient(grpcClient)
	app := fiber.New()

	app.Get("/", func(c fiber.Ctx) error {
		resp, err := fooServiceClient.FooMethod(c.UserContext(), &hello_grpc.YourRequest{
			Message: "Hello",
		})
		if err != nil {
			return err
		}
		return c.SendString(resp.GetMessage())
	})

	app.Listen(":3000")
}
